﻿using Infrastructure;
using Senparc.Weixin.MP.AdvancedAPIs;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
using WsdShop.IService;
using WsdShop.Model;
using WsdShop.Model.Enum;
using WsdShop.Service;

namespace WeChat.Controllers
{
    public class DrawController : BaseController
    {
        #region 构造
        private IDrawService drawService;
        private IActivityTeamMembersService activityteammembersservice;
        private IWxConfigService configService;
        private IOrderService orderservice;
        private ICommonAreaService commonAreaService;
        private IDrawAdminService drawAdminService;
        private IWxConfigService wxConfigService;
        private string checkUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}";

        public DrawController(IMemberService s, IDrawService d, IActivityTeamMembersService _activityteammembersservice, IWxConfigService _configService, ICommonAreaService c, IOrderService _orderservice,IDrawAdminService d1,IWxConfigService w) : base(s)
        {
            drawService = d;
            activityteammembersservice = _activityteammembersservice;
            configService = _configService;
            orderservice = _orderservice;
            commonAreaService = c;
            drawAdminService = d1;
            wxConfigService = w;
        }

        #endregion

        #region 积分抽奖逻辑
        public ActionResult Index(int drawId = 0, int tId = 0)
        {
            if (tId > 0)
            {
                var draws = BaseService.LoadEntities<Draw>(d => d.Id == drawId).FirstOrDefault();
                if (draws == null)
                {
                    return RedirectToAction("Failed", new { reason = "抱歉，目前没有上架的抽奖活动" });
                }
                ViewBag.Draw = draws;
                return View();
            }
            else
            {
                #region 判断有无可抽奖的活动
                var draws = BaseService.LoadEntities<Draw>(d => d.IsDeleted == false && d.IsDisplay);
                var draw = draws.Where(d => d.StartTime < DateTime.Now && d.EndTime > DateTime.Now).OrderByDescending(d => d.Sort).FirstOrDefault();
                if (draw == null)
                {
                    return RedirectToAction("Failed", new { reason = "抱歉，目前没有上架的抽奖活动" });
                }
                #endregion
                #region 判断能否抽奖
                var member = _memberService.GetMemberInfo(CurrentLoginUser.Id);
                //if (member.Points < draw.ConsumePoints)
                //{
                //    return RedirectToAction("Failed", new { reason = $@"您的积分不够，本次抽奖需消耗{draw.ConsumePoints}点积分" });
                //}

                //if (draw.Chances > 0)
                //{
                //    var records = BaseService.LoadEntities<DrawRecord>(r => r.DrawId == draw.Id && r.IsDeleted == false && r.MemberId == member.Id);
                //    if (records.Count >= draw.Chances)
                //    {
                //        return RedirectToAction("Failed", new { reason = "您本次活动的抽奖机会已经用完了，请等下次活动吧" });
                //    }
                //}

                //var sign = BaseService.LoadEntities<MemberSign>(s => s.IsDeleted == false).OrderByDescending(s => s.SignDate).FirstOrDefault();
                ////若今天没签到，则提示先签到
                //if (sign == null || sign.SignDate.Date != DateTime.Now.Date)
                //{
                //    return RedirectToAction("Failed", new { reason = "请先签到,连续7天签到才可抽奖！" });
                //}
                //if (sign.SignCount < 7)
                //{
                //    return RedirectToAction("Failed", new { reason = "连续7天签到才可抽奖！" });
                //}

                #endregion
                ViewBag.Draw = draw;
                return View();
            }
        }

        //异步获取奖项
        public ActionResult DrawInfo(int actId = 0)
        {
            var model = BaseService.LoadEntities<DrawReward>(r => r.IsDeleted == false && r.DrawId == actId);
            if (model.Count > 12)
            {
                return Json(Result.Failure("奖品数据读取错误"));
            }
            var result = Result.Success();
            result.data = model;
            return Json(result);
        }

        public ActionResult StartDraw(int actId = 0, int tId = 0)
        {
            try
            {
                var member = _memberService.GetMemberInfo(CurrentLoginUser.Id);
                var draw = BaseService.LoadEntity<Draw>(d => d.Id == actId);//进入抽奖页面就不判断活动过不过期了。
                if (draw == null)
                {
                    return Json(Result.Failure("抱歉，本活动已经被删除"));
                }
                //一分钱过来的
                if (tId > 0)
                {
                   

                    int total = 0;
                    var teammember = activityteammembersservice.GetActivityTeamMembersInfo(tId, ref total);

                    if (teammember == null || teammember.UserId != CurrentLoginUser.Id)
                    {
                        return Json(Result.Failure("查不到该订单！"));
                    }

                    if (teammember.TeamStatus != 2)
                    {
                        return Json(Result.Failure("该团未拼成功！"));
                    }

                    if (teammember.WinningStatus != 4)
                    {
                        return Json(Result.Failure("该订单已抽过奖！"));
                    }
                    var prize = drawService.Draw(actId);
                    bool success = orderservice.YiFenDraw(actId, CurrentLoginUser, teammember, ref prize);
                    if (!success)
                    {
                        return Json(Result.Failure("抱歉，出错了，请联系管理员"));
                    }

                    if (prize == null)
                    {
                        //没中退款给
                        var rt = Refund(teammember.OrderNo, teammember.OrderNo, (teammember.PaymentAmount * 100).ToString("0"), (teammember.PaymentAmount * 100).ToString("0"));
                        var res = XDocument.Parse(rt);
                        string return_code = "";
                        if (res != null && res.Element("xml") != null)
                        {
                            return_code = res.Element("xml").Element("return_code").Value;
                            //out_trade_no = res.Element("xml").Element("out_trade_no").Value;
                            //transaction_id = res.Element("xml").Element("transaction_id").Value;
                        }
                        if (return_code.ToUpper() == "SUCCESS" && res.Element("xml").Element("err_code") == null)
                        {
                            var config = wxConfigService.GetConfig();
                            string token = wxConfigService.GetCurrentToken(checkUrl, config.AppId, config.AppSecret);
                            CustomApi.SendText(token, member.OpenId, $"您收到来自一分钱活动的退款,退款金额为{teammember.PaymentAmount}元。");
                        }
                            prize = new DrawReward() { Id = 0, RewardName = "谢谢参与" };
                    }


                    var result = Result.Success();
                    result.data = prize;
                    return Json(result);
                }
                else
                {

                    if (member.Points < draw.ConsumePoints)
                    {
                        return Json(Result.Failure($@"您的积分不够了！本次抽奖需花费{draw.ConsumePoints}点积分"));
                    }

                    //var sign = BaseService.LoadEntities<MemberSign>(s => s.IsDeleted == false).OrderByDescending(s => s.SignDate).FirstOrDefault();
                    //if (sign == null || sign.SignDate.Date != DateTime.Now.Date)
                    //{
                    //    //return RedirectToAction("Failed", new { reason = "请先签到,连续7天签到才可抽奖！" });
                    //    return Json(Result.Failure("请先签到,连续7天签到才可抽奖！"));
                    //}
                    //if (sign.SignCount < 7)
                    //{
                    //    //return RedirectToAction("Failed", new { reason = "连续7天签到才可抽奖！" });
                    //    return Json(Result.Failure("连续签到7天才可抽奖！"));
                    //}

                    //如果Chances等于0，则不限次数
                    if (draw.Chances > 0)
                    {
                        var records = BaseService.LoadEntities<DrawRecord>(r => r.DrawId == draw.Id && r.IsDeleted == false && r.MemberId == member.Id);
                        if (records.Count >= draw.Chances)
                        {
                            return Json(Result.Failure("您已经用完了本次活动的抽奖机会，下次继续吧！"));
                        }
                    }
                    var prize = drawService.Draw(actId);

                    if(prize != null && prize.RewardType == RewardType.实体商品)
                    {
                        var config = wxConfigService.GetConfig();
                        var token = wxConfigService.GetCurrentToken(checkUrl, config.AppId, config.AppSecret);
                        CustomApi.SendTextAsync(token, member.OpenId, $"恭喜您获得幸运大奖，稍后我们会为您派发奖品，请您耐心等待。");
                    }

                    #region 生成消耗积分的明细纪录
                    var balanceDetail = new MemberBalanceDetail()
                    {
                        AddTime = DateTime.Now,
                        IsDeleted = false,
                        MemberId = member.Id,
                        Point = 0 - draw.ConsumePoints,
                        MemberAmount = member.Balance,
                        MemberPoint = member.Points,
                        Note = "积分抽奖消耗",
                        AddUserId = 0,
                    };
                    _memberService.AddMemberBalanceDetail(balanceDetail);
                    #endregion
                    #region 生成抽奖记录
                    var record = new DrawRecord()
                    {
                        AddTime = DateTime.Now,
                        DrawId = actId,
                        IsDeleted = false,
                        MemberId = member.Id,
                        MemberName = member.NickName,
                        ConsumePoints = draw.ConsumePoints
                    };

                    if (prize == null)
                    {
                        record.StepType = StepType.已发放;
                        record.IsWinning = false;
                        record.DrawRewardId = 0;
                        record.ProductNum = 0;
                    }
                    else
                    {
                        record.StepType = StepType.待确认收货地址;
                        record.IsWinning = true;
                        record.DrawRewardId = prize.Id;
                        record.ProductSecpId = prize.ProductSecpId;
                        record.ProductName = prize.ProductName;
                        record.ProductNum = prize.Points;
                        record.DrawRewardName = prize.RewardName;
                        record.RewardType = prize.RewardType;
                    }
                    //更新用户积分
                    //member.Points = member.Points - draw.ConsumePoints;
                    if (record.RewardType == RewardType.奖励积分)
                    {
                        var detail = new MemberBalanceDetail()
                        {
                            AddTime = DateTime.Now,
                            IsDeleted = false,
                            MemberId = member.Id,
                            Point = prize.Points,
                            MemberAmount = member.Balance,
                            MemberPoint = member.Points,
                            Note = "积分抽奖奖品",
                            AddUserId = 0,
                        };
                        _memberService.AddMemberBalanceDetail(detail);
                        record.StepType = StepType.已发放;
                    }
                    //如果是优惠券，则更新用户优惠券表
                    if (record.RewardType == RewardType.优惠券)
                    {
                        var memberCoupon = new MemberCoupon()
                        {
                            AddTime = DateTime.Now,
                            IsDeleted = false,
                            SourceType = MemberCouponSource.积分抽奖,
                            CouponId = record.ProductSecpId,
                            MemberId = member.Id,
                            Status = MemberCouponStatus.未使用,
                        };
                        BaseService.AddEntity(memberCoupon);
                        record.StepType = StepType.已发放;
                    }
                    //BaseService.UpdateEntity(member);
                    #endregion
                    BaseService.AddEntity(record);
                    var result = Result.Success();
                    if (prize == null)
                    {
                        prize = new DrawReward() { Id = 0, RewardName = "谢谢参与" };
                    }
                    result.data = prize;
                    return Json(result);
                }
            }
            catch (Exception ex)
            {
                return Json(Result.Failure(ex.Message));
            }
        }

        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            if (errors == SslPolicyErrors.None)
                return true;
            return false;
        }
        /// <summary>
        /// 退款申请接口
        /// </summary>
        /// <param name="out_trade_no">填入商家订单号</param>
        /// <param name="out_refund_no">填入退款订单号</param>
        /// <param name="total_fee">填入总金额</param>
        /// <param name="refund_fee">填入退款金额</param>
        /// <returns></returns>
        public string Refund(string out_trade_no, string out_refund_no, string total_fee, string refund_fee)
        {
            //string appId = ConfigurationManager.AppSettings["AppId"];
            //string key = ConfigurationManager.AppSettings["Key"];
            //string mchId = ConfigurationManager.AppSettings["MchId"];
            var config = configService.GetConfig();

            string appId = config.AppId;
            string key = config.PaySignKey;
            string mchId = config.PartnerID;
            string certUrl = Server.MapPath("/cert/apiclient_cert.p12");
            string nonceStr = Senparc.Weixin.MP.TenPayLibV3.TenPayV3Util.GetNoncestr();
            Senparc.Weixin.MP.TenPayLibV3.RequestHandler packageReqHandler = new Senparc.Weixin.MP.TenPayLibV3.RequestHandler(null);

            //设置package订单参数
            packageReqHandler.SetParameter("appid", appId); //公众账号ID
            packageReqHandler.SetParameter("mch_id", mchId); //商户号
            packageReqHandler.SetParameter("out_trade_no", out_trade_no); //填入商家订单号
            packageReqHandler.SetParameter("out_refund_no", out_refund_no); //填入退款订单号
            packageReqHandler.SetParameter("total_fee", total_fee); //填入总金额
            packageReqHandler.SetParameter("refund_fee", refund_fee); //填入退款金额
            packageReqHandler.SetParameter("op_user_id", mchId); //操作员Id，默认就是商户号
            packageReqHandler.SetParameter("nonce_str", nonceStr); //随机字符串
            string sign = packageReqHandler.CreateMd5Sign("key", key);
            packageReqHandler.SetParameter("sign", sign); //签名
            //退款需要post的数据
            string data = packageReqHandler.ParseXML();

            //退款接口地址
            string url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
            //本地或者服务器的证书位置（证书在微信支付申请成功发来的通知邮件中）
            string cert = certUrl;
            //私钥（在安装证书时设置）
            string password = mchId;
            ServicePointManager.ServerCertificateValidationCallback =
                new RemoteCertificateValidationCallback(CheckValidationResult);
            //调用证书
            X509Certificate2 cer = new X509Certificate2(cert, password,
                X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

            #region 发起post请求

            HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
            webrequest.ClientCertificates.Add(cer);
            webrequest.Method = "post";

            byte[] postdatabyte = Encoding.UTF8.GetBytes(data);
            webrequest.ContentLength = postdatabyte.Length;
            Stream stream;
            stream = webrequest.GetRequestStream();
            stream.Write(postdatabyte, 0, postdatabyte.Length);
            stream.Close();

            HttpWebResponse httpWebResponse = (HttpWebResponse)webrequest.GetResponse();
            StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
            string responseContent = streamReader.ReadToEnd();

            #endregion

            var res = XDocument.Parse(responseContent);
            return responseContent;
        }


        public ActionResult Failed(string reason)
        {
            ViewBag.Reason = reason;
            return View();
        }
        #endregion

        public ActionResult RecordList()
        {
            return View();
        }

        public ActionResult GetRecordList()
        {
            var list = BaseService.LoadEntities<DrawRecord>(r => r.MemberId == CurrentLoginUser.Id && r.IsDeleted == false && r.IsWinning).OrderByDescending(d => d.AddTime).ToList();
            var result = Result.Success();
            result.data = list;
            return Json(result);
        }

        public ActionResult SetAddress()
        {
            return View();
        }

        public ActionResult GetProduct(int id)
        {
            var record = BaseService.LoadEntity<DrawRecord>(r => r.Id == id);
            if (record == null || record.RewardType != RewardType.实体商品)
            {
                return Json(Result.Failure("数据出错"));
            }
            //var pro = BaseService.LoadEntity<Product>(p => p.Id == record.ProductSecpId && p.IsDeleted == false);//这里暂时不加入判断下架逻辑，下架也得发货
            var pro = drawAdminService.GetSpecById(record.ProductSecpId);
            if (pro == null)
            {
                return Json(Result.Failure("商品不存在"));
            }
            var result = Result.Success();
            result.data = pro;
            return Json(result);
        }

        //设置收货地址
        public ActionResult SubmitAddress(DrawRecord record)
        {
            var model = BaseService.LoadEntity<DrawRecord>(r => r.Id == record.Id);
            if (model == null)
            {
                return Json(Result.Failure("订单已经不存在，无法设置"));
            }
            int cd = Convert.ToInt32(record.City);
            int dd = Convert.ToInt32(record.District);
            int pd = Convert.ToInt32(record.Province);
            model.Consignee = record.Consignee;
            var city = commonAreaService.GetArea(cd);
            model.City = city.Name;
            var dist = commonAreaService.GetArea(dd);
            model.District = dist.Name;
            var pro = commonAreaService.GetArea(pd);
            model.Province = pro.Name;
            model.Zipcode = record.Zipcode;
            model.Mobile = record.Mobile;
            model.Address = record.Address;
            model.StepType = StepType.待发放;//设置完地址后变成待发放状态
            BaseService.UpdateEntity(model);
            return Json(Result.Success());
        }



    }
}